#include <iostream>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <cstring>
// #include <netinet/in.h>
#include <arpa/inet.h>
#include "tcpLib.h"
#include <unistd.h>

#define LISTEN_SIZE 128
#define MASSAGE_SIZE 128
bool TcpServer::tcpServerInit()
{
    m_sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (m_sockfd <= 0)
    {
        perror("socket error");
        return false;
    }
    struct sockaddr_in serverAddr;
    memset(&serverAddr, 0, sizeof(sockaddr_in));
    socklen_t serverLen = sizeof(serverAddr);
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(m_port);
    /*将ip转化为网络格式地址*/
    int ret = inet_pton(AF_INET, m_ip.c_str(), (void *)&serverAddr.sin_addr.s_addr);
    if (ret == -1)
    {
        perror("inet_pton error");
        return false;
    }
    /*设置端口复用*/
    int portOption = 1;
    ret = setsockopt(m_sockfd, SOCK_STREAM, SO_REUSEADDR, (void *)&portOption, sizeof(portOption));
    if (ret != 0)
    {
        perror("setsockopt error");
        return false;
    }
    ret = bind(m_sockfd, (struct sockaddr *)&serverAddr, serverLen);
    if (ret != 0)
    {
        perror("bind error");
    }
    ret = listen(m_sockfd, LISTEN_SIZE);
    if (ret != 0)
    {
        perror("listen error");
    }

    return true;
}
bool TcpServer::tcpServerAccept()
{
    struct sockaddr_in clientAddr;
    memset(&clientAddr, 0, sizeof(clientAddr));
    socklen_t clientLen = sizeof(clientAddr);
    int acceptfd = accept(m_sockfd, (struct sockaddr *)&clientAddr, &clientLen);
    if (acceptfd == -1)
    {
        perror("accept error");
        return false;
    }
    m_acceptfd = acceptfd;
    printf("accept ok!\n");
    return true;
}
/*读取*/
std::string TcpServer::tcpServerRead()
{
    /*接收信息*/
    char recMessage[MASSAGE_SIZE];
    // std::string recMessage;
    // recMessage.clear();
    int ret = read(m_acceptfd, recMessage, sizeof(recMessage));
    if (ret < 0)
    {
        perror("read error");
        close(m_acceptfd);
    }
    else if (ret == 0)
    {
        std::cout << "客户端下线\n";
        close(m_acceptfd);
    }
    else
    {
        std::cout << "client message:" << recMessage << std::endl;
        return recMessage;
    }
    return "";
}
/*发送*/
bool TcpServer::tcpServerWrite(const std::string &sendMessage)
{
    /*接收信息*/
    // char recMessage[MASSAGE_SIZE];

    int ret = write(m_acceptfd, sendMessage.c_str(), 128);
    if (ret < 0)
    {
        perror("read error");
        close(m_acceptfd);
        return false;
    }
    else if (ret == 0)
    {
        std::cout << "客户端下线\n";
        return false;
    }
    else
    {
        printf("write success\n");
        return true;
    }
}
/*销毁*/
bool TcpServer::tcpServerDestroy()
{
    close(m_acceptfd);
    close(m_sockfd);
    return true;
}
/*初始化客户端*/
bool TcpClient::TcpClientInit()
{
    m_sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (m_sockfd == -1)
    {
        perror("socket error");
        return false;
    }

    /*第二步：connect函数*/
    struct sockaddr_in clientAddr;
    memset(&clientAddr, 0, sizeof(clientAddr));
    /*处理函数参数*/
    clientAddr.sin_family = AF_INET;
    clientAddr.sin_port = htons(m_port);
    const char *localIp = m_ip.c_str();
    int ret = inet_pton(AF_INET, localIp, (void *)&clientAddr.sin_addr.s_addr);
    if (ret == -1)
    {
        perror("inet_pton error");
        return false;
    }
    ret = connect(m_sockfd, (struct sockaddr *)&clientAddr, sizeof(clientAddr));
    if (ret == -1)
    {
        perror("connect error");
        return false;
    }
    return true;
}
/*读取*/
std::string TcpClient::TcpClientRead()
{
    char recMessage[MASSAGE_SIZE] = {0};
    printf("------\n");
    int ret = read(m_sockfd, recMessage, sizeof(recMessage));
    if (ret < 0)
    {
        perror("read error");
        close(m_sockfd);
    }
    else if (ret == 0)
    {
        std::cout << "服务器下线\n";
        close(m_sockfd);
    }
    else
    {
        std::cout << "server message:" << recMessage << std::endl;
        return recMessage;
    }
    return "";
}
/*发送*/
bool TcpClient::TcpClientWrite(const std::string &sendMessage)
{
    int ret = write(m_sockfd, sendMessage.c_str(), 128);
    if (ret < 0)
    {
        perror("write error");
        close(m_sockfd);
        return false;
    }
    else if (ret == 0)
    {
        std::cout << "服务器下线\n";
        return false;
    }
    else
    {
        return true;
    }
}
/*销毁*/
bool TcpClient::TcpClientDestroy()
{
    close(m_sockfd);
    return true;
}